iT邦幫忙

2024 iThome 鐵人賽

DAY 29
0
Kubernetes

都什麼年代了,還在學 Kubernetes系列 第 29

學 Kubernetes 的第二十九天 - Resource - Namespace 層級的資源管理

  • 分享至 

  • xImage
  •  

當多個團隊或使用者共用同一個 Kubernetes 叢集時,資源競爭是很常見的。為了避免某個團隊的資源使用影響到其他團隊,我們可以使用資源配額來進行限制。在 Kubernetes 中,可以透過命名空間 (namespace) 來分隔不同的團隊,並使用 ResourceQuotaLimitRange 來管理資源。

Resource Quotas

ResourceQuota 是 Kubernetes 提供的機制,用來限制特定 namespace 中可以使用的資源總量。透過 Resource Quotas,可以限制該 namespace 中可創建的 Pod、Service、PersistentVolumeClaim(PVC)等資源數量,以及這些資源的總 CPU 和記憶體用量。如果資源申請超過了配額限制,新的申請會被拒絕。

功能

  • 限制資源數量:限制 namespace 中各種資源的數量,如 Pod、Service、ConfigMap。
  • 限制資源總量:限制 namespace 中資源的總使用量,如 CPU、記憶體等。

資源配額的類型

  • 計算資源配額 (Compute Resource Quota):限制 CPU、記憶體等計算資源的使用上限。
  • 儲存資源配額 (Storage Resource Quota):限制 PVC、storage-class 的申請數量或容量上限。
  • 對象數量配額 (Object Count Quota):限制 Pod、Service、Deployments 等資源的數量上限。

以下是一個 Resource Quota 的範例配置:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-quota
spec:
  hard:
    pods: "10"  # 限制該 namespace 中最多可以創建 10 個 Pod
    requests.cpu: "4"  # 限制 CPU 的總請求數為 4 核心
    requests.memory: "8Gi"  # 限制記憶體的總請求數為 8 GiB
    limits.cpu: "8"  # 限制 CPU 的總限制數為 8 核心
    limits.memory: "16Gi"  # 限制記憶體的總限制數為 16 GiB

Limit Ranges

LimitRange 用來控制 namespace 中容器和 Pod 的資源使用範圍,可以設定最小(min)和最大(max)資源請求和限制,並提供默認的資源配置值。

功能

  • 設定資源範圍:設定容器的最小和最大資源請求和限制,防止某個容器使用過多或過少的資源。
  • 設定默認資源值:設定 namespace 中的默認資源請求和限制,確保新創建的 Pod 有合理的資源配置。

以下是一個 Limit Range 的範例配置:

apiVersion: v1
kind: LimitRange
metadata:
  name: my-limit-range
spec:
  limits:
  - type: Container
    max:
      cpu: "2"  # 每個容器最多使用 2 核心 CPU
      memory: "1Gi"  # 每個容器最多使用 1 GiB 記憶體
    min:
      cpu: "100m"  # 每個容器至少使用 100m CPU
      memory: "128Mi"  # 每個容器至少使用 128 MiB 記憶體
    default:
      cpu: "500m"  # 容器默認使用 500m CPU
      memory: "256Mi"  # 容器默認使用 256 MiB 記憶體
    defaultRequest:
      cpu: "250m"  # 容器默認的資源請求值為 250m CPU
      memory: "128Mi"  # 容器默認的資源請求值為 128 MiB 記憶體

透過這些策略,我們可以有效地避免資源的過度使用,確保每個團隊都能獲得公平的資源分配。

實作 Resource Quotas

建立一個名字空間,以便將本練習所建立的資源與叢集的其餘資源相隔離。

  • 建立 namespace
kubectl create ns manage-resources-ns

計算資源配額

組態檔案:resource-quota-compute.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-resource-quota
  namespace: manage-resources-ns
spec:
  hard:
    requests.cpu: "1"
    requests.memory: 1Gi
    limits.cpu: "2"
    limits.memory: 2Gi
  • 查看 ResourceQuota
kubectl -n manage-resources-ns describe resourcequotas my-resource-quota
---
Name:            my-resource-quota
Namespace:       manage-resources-ns
Resource         Used  Hard
--------         ----  ----
limits.cpu       0     2
limits.memory    0     2Gi
requests.cpu     0     1
requests.memory  0     1Gi

建立 Pod

組態檔案:compute-resources-pod-1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod1
  namespace: manage-resources-ns
spec:
  containers:
  - name: c1
    image: nginx
    resources:
      limits:
        memory: "800Mi"
        cpu: "800m"
      requests:
        memory: "600Mi"
        cpu: "400m"
  • 建立 Pod
kubectl apply -f compute-resources-pod-1.yaml
  • 查看 Pod
kubectl -n manage-resources-ns describe resourcequotas my-resource-quota
---
Name:            my-resource-quota
Namespace:       manage-resources-ns
Resource         Used   Hard
--------         ----   ----
limits.cpu       800m   2
limits.memory    800Mi  2Gi
requests.cpu     400m   1
requests.memory  600Mi  1Gi

建立超出配額的資源

組態檔案:compute-resources-pod-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod2
  namespace: manage-resources-ns
spec:
  containers:
  - name: c1
    image: nginx
    resources:
      limits:
        memory: "1Gi"
        cpu: "800m"
      requests:
        memory: "700Mi"
        cpu: "400m"

request.memory 600Mi + 700Mi > 1G,會超過請求上限

  • 建立 Pod
kubectl apply -f compute-resources-pod-2.yaml
---
Error from server (Forbidden): error when creating "compute-resources-pod-2.yaml": pods "pod2" is forbidden: exceeded quota: my-resource-quota, requested: requests.memory=700Mi, used: requests.memory=600Mi, limited: requests.memory=1Gi

可以看到,超出上限的請求,叢集回報 403 (Forbidden) 錯誤,並且給與錯誤訊息。

對象數量限制

組態檔案:resource-quota-count.yaml

apiVersion: v1
kind: ResourceQuota
metadata:
  name: my-resource-quota
  namespace: manage-resources-ns
spec:
  hard:
    configmaps: "10"
    persistentvolumeclaims: "4"
    replicationcontrollers: "20"
    secrets: "10"
    services: "10"
    services.loadbalancers: "2"
  • 建立 Pod
kubectl apply -f resource-quota-count.yaml
  • 查看 Pod
kubectl -n manage-resources-ns describe resourcequotas my-resource-quota
---
Name:                   my-resource-quota
Namespace:              manage-resources-ns
Resource                Used  Hard
--------                ----  ----
configmaps              1     10
persistentvolumeclaims  0     4
replicationcontrollers  0     20
secrets                 0     10
services                0     10
services.loadbalancers  0     2

實作 Limit Ranges

組態檔案:limit-range.yaml

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
  namespace: manage-resources-ns
spec:
  limits:
  - default:
      memory: 1Gi
      cpu: 1
    defaultRequest:
      memory: 500Mi
      cpu: 0.5
    max:
      memory: 2Gi
      cpu: 2
    min:
      memory: 128Mi
      cpu: 0.1
    type: Container
  • default:當 Pod 或容器沒有指定資源限制時,帶入該值。

  • defaultRequest:當 Pod 或容器沒有指定資源請求時,帶入該值。

  • max:Pod 或容器可以請求或限制的資源最大值為該值。

  • min:Pod 或容器必須請求或限制的資源最小值為該值。

  • type:指定這些限制適用於容器級別。

  • 查看 LimitRange

kubectl -n manage-resources-ns describe limitranges my-limit-range

結果如下

Name:       my-limit-range
Namespace:  manage-resources-ns
Type        Resource  Min    Max  Default Request  Default Limit  Max Limit/Request Ratio
----        --------  ---    ---  ---------------  -------------  -----------------------
Container   memory    128Mi  2Gi  500Mi            1Gi            -
Container   cpu       100m   2    500m             1              -

建立沒有請求和限制的 Pod

組態檔案: limit-range-pod-1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod1
  namespace: manage-resources-ns
spec:
  containers:
  - name: c1
    image: nginx
  • 查看 Pod 詳情
kubectl -n manage-resources-ns get pod pod1 -o jsonpath='{range .spec.containers[*]}{.name}{"\n"}{.resources}{"\n\n"}{end}'

結果如下

    Limits:
      cpu:     1
      memory:  1Gi
    Requests:
      cpu:        500m
      memory:     500Mi

可以看到,建立沒有請求和限制的 Pod,其請求和限制會自動帶入 limit-range 裡的 default, defaultRequest。

建立請求低於資源最小值的 Pod

組態檔案: limit-range-pod-2.yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod2
  namespace: manage-resources-ns
spec:
  containers:
  - name: c1
    image: nginx
    resources:
      requests:
        memory: 100Mi
  • 建立 Pod 時,會回報 403 (Forbidden) 錯誤,並且給你錯誤訊息:
Error from server (Forbidden): error when creating "`limit-range-pod-2.yaml": pods "pod2" is forbidden: minimum memory usage per Container is 128Mi, but request is 100Mi

可以看到,建立低於 LimitRanges 請求的資源時,叢集回報 403 (Forbidden) 錯誤,並且給與錯誤訊息。

清理

  • 刪除命名空間
kubectl delete namespace manage-resources-ns

小結

Kubernetes 的 ResourceQuotaLimitRange 是非常有效的資源管理工具,能夠確保多個團隊,在同一叢集中公平地使用資源。透過這些配額和限制,每個團隊都能擁有足夠的資源去完成他們的工作,同時也避免了資源的浪費和搶奪。

最後我們再快速複習一遍:

  • Resource Quotas 用於限制 namespace 中的資源總量,防止某個 namespace 過度使用叢集資源。
  • Limit Ranges 用於限制每個容器或 Pod 的資源使用範圍,確保資源的合理分配。

參考


上一篇
學 Kubernetes 的第二十八天 - Resource - Pod 層級的資源管理
下一篇
學 Kubernetes 的第三十天 - 中場休息 + 完賽感言
系列文
都什麼年代了,還在學 Kubernetes37
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言